﻿using log4net;
using Microsoft.International.Converters.PinYinConverter;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Numerics;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace PhysicalExamination5.Service
{
    public class MethodHelper
    {
        /// <summary>
        /// 加密秘钥 8位
        /// </summary>
        string strMD5Key = "mysoft@2";
        /// <summary>
        /// 日志对象
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(MethodHelper));
        /// <summary>
        /// 数据库对象
        /// </summary>
        private readonly ISqlSugarClient db;
        /// <summary>
        /// Aes秘钥
        /// </summary>
        public string ClsAesKey = "ACCSEOPCSOWQJSDM";
        /// <summary>
        /// Aes IV值
        /// </summary>
        public string ClsAesIv = "mysoft@2mysoft@1";


        public MethodHelper(ISqlSugarClient db)
        {
            this.db = db;
        }




        /// <summary>
        /// AESCBC加密
        /// </summary>
        /// <param name="toEncrypt"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public string AesEncrypt(string toEncrypt)
        {
            try
            {
                byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
                byte[] keyArray = Encoding.UTF8.GetBytes(ClsAesKey);//注意编码格式(utf8编码 UTF8Encoding)
                byte[] ivArray = Encoding.UTF8.GetBytes(ClsAesIv);

                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.IV = ivArray;
                rDel.Mode = CipherMode.CBC;
                //rDel.Padding = PaddingMode.Zeros;

                ICryptoTransform cTransform = rDel.CreateEncryptor();//加密
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                return Convert.ToBase64String(resultArray, 0, resultArray.Length);

            }
            catch (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// AesCBC解密
        /// </summary>
        /// <param name="toDecrypt"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public string AesDecrypt(string toDecrypt)
        {
            try
            {
                byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);

                byte[] keyArray = Encoding.UTF8.GetBytes(ClsAesKey);//注意编码格式(utf8编码 UTF8Encoding)
                byte[] ivArray = Encoding.UTF8.GetBytes(ClsAesIv);

                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.IV = ivArray;
                rDel.Mode = CipherMode.CBC;
                //rDel.Padding = PaddingMode.Zeros;

                ICryptoTransform cTransform = rDel.CreateDecryptor();//解密
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                return Encoding.UTF8.GetString(resultArray);
            }
            catch (Exception ex)
            {

                return "";
            }

        }


        /// <summary>
        /// 校验人员姓名是否正确
        /// </summary>
        /// <param name="nameStr"></param>
        /// <returns></returns>
        public bool CheckName(string nameStr) //检查姓名是否合法
        {
            Regex nameReg = new Regex(@"^[\u4e00-\u9fa5]{0,}$");//为汉字
            Regex nameReg2 = new Regex(@"^\w+$");//字母，数字，下划线
            if (nameReg.IsMatch(nameStr) || nameReg2.IsMatch(nameStr))//为汉字或字母
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 验证身份证是否有效
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public bool IsIDCard(string Id)
        {
            if (Id.Length == 18)
            {
                bool check = IsIDCard18(Id);
                return check;
            }
            else if (Id.Length == 15)
            {
                bool check = IsIDCard15(Id);
                return check;
            }
            else
            {
                return false;
            }
        }

        public bool IsIDCard18(string Id)
        {
            long n = 0;
            if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            string[] arrVarifyCode = "1,0,x,9,8,7,6,5,4,3,2".Split(',');
            string[] Wi = "7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2".Split(',');
            char[] Ai = Id.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());
            }
            int y = -1;
            Math.DivRem(sum, 11, out y);
            if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
            {
                return false;//校验码验证
            }
            return true;//符合GB11643-1999标准
        }
        public bool IsIDCard15(string Id)
        {
            long n = 0;
            if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            return true;//符合15位身份证标准
        }

        /// <summary>
        /// 根据出生日期，计算精确的年龄
        /// </summary>
        /// <param name="birthDate">生日</param>
        /// <returns></returns>
        public int CalculateAge(string birthDay)
        {
            DateTime birthDate = DateTime.Parse(birthDay);
            DateTime nowDateTime = DateTime.Now;
            int age = nowDateTime.Year - birthDate.Year;
            //再考虑月、天的因素
            if (nowDateTime.Month < birthDate.Month || nowDateTime.Month == birthDate.Month && nowDateTime.Day < birthDate.Day)
            {
                age--;
            }
            return age;
        }


        /// <summary>
        /// 验证手机号
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public bool IsMobile(string source)
        {
            return Regex.IsMatch(source, @"^1[3456789]\d{9}$", RegexOptions.IgnoreCase);
        }


        /// <summary>
        /// 获取出生日期和年龄
        /// </summary>
        /// <param name="strFanHuiZhi"></param>
        /// <param name="birthday"></param>
        /// <param name="sex"></param>
        /// <param name="identityCard"></param>
        /// <returns></returns>
        public int HuoQuAgeBirthday(out string strFanHuiZhi, out string birthday, out string sex, string identityCard)
        {
            int nret = 0; strFanHuiZhi = ""; birthday = ""; sex = "";
            try
            {
                if (identityCard.Length == 18)
                {
                    birthday = identityCard.Substring(6, 4) + "-" + identityCard.Substring(10, 2) + "-" + identityCard.Substring(12, 2);
                    sex = identityCard.Substring(14, 3);
                }
                //处理15位的身份证号码从号码中得到生日和性别代码
                if (identityCard.Length == 15)
                {
                    birthday = "19" + identityCard.Substring(6, 2) + "-" + identityCard.Substring(8, 2) + "-" + identityCard.Substring(10, 2);
                    sex = identityCard.Substring(12, 3);
                }

                if (int.Parse(sex) % 2 == 0)
                {
                    sex = "女";
                }
                else
                {
                    sex = "男";
                }

                return nret;
            }
            catch (Exception ex)
            {
                return 1000;
            }
        }


        public class QingQiuFanHui
        {
            /// <summary>
            /// 
            /// </summary>
            public int Success { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string Message { get; set; }
            /// <summary>
            ///
            /// </summary>
            public string data { get; set; }
        }



        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string GetMD5Hash(string input)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

                StringBuilder builder = new StringBuilder();

                for (int i = 0; i < data.Length; i++)
                {
                    builder.Append(data[i].ToString("x2"));
                }

                return builder.ToString();
            }
        }

        /// <summary>
        /// httpGet请求
        /// </summary>
        /// <param name="strFanHuiZhi"></param>
        /// <param name="weburl"></param>
        /// <param name="data"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        private int PushToWebGet(out string strFanHuiZhi, string weburl, string data, Encoding encode)
        {
            object objFanHuiZhi; string JiaMiKey = "";
            try
            {
                if (data.Contains("#")) { data = data.Replace("#", ""); }

                //获取当前时间戳
                DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
                long logDangQianTime = (long)(DateTime.Now - startTime).TotalSeconds; // 相差秒数
                //加密内容
                JiaMiKey = AesEncrypt(logDangQianTime.ToString());

                weburl = weburl + "?" + data;
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(weburl));
                webRequest.Method = "GET";
                webRequest.ContentType = "text/plain";
                webRequest.Headers.Add("CheckKey", JiaMiKey);
                //接收返回信息：
                HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
                StreamReader aspx = new StreamReader(response.GetResponseStream(), encode);
                strFanHuiZhi = aspx.ReadToEnd();
                return 0;
            }
            catch (Exception ex)
            {
                strFanHuiZhi = ex.ToString();
                return -1;
            }
        }



        /// <summary>
        /// 从URL上下载pdf文件，保存到本地
        /// </summary>
        /// <param name="saveLoadFile">保存文件的路径</param>
        /// <param name="pdfFile">PDF文件的URL地址</param>
        /// <returns></returns>
        public int SaveRemoteFile(out string strFanHuiZhi, string saveLoadFile, string pdfFile)
        {
            strFanHuiZhi = ""; int nret = 0;
            try
            {
                var f = saveLoadFile;
                Uri downUri = new Uri(pdfFile);
                //建立一个web请求，返回HttpWebRequest对象
                HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(downUri);
                //流对象使用完后自动关闭
                using (Stream stream = hwr.GetResponse().GetResponseStream())
                {
                    //文件流，流信息读到文件流中，读完关闭
                    using (FileStream fs = File.Create(f))
                    {
                        //建立字节组，并设置它的大小是多少字节
                        byte[] bytes = new byte[102400];
                        int n = 1;
                        while (n > 0)
                        {
                            //一次从流中读多少字节，并把值赋给Ｎ，当读完后，Ｎ为０,并退出循环
                            n = stream.Read(bytes, 0, 10240);
                            fs.Write(bytes, 0, n); //将指定字节的流信息写入文件流中
                        }
                    }
                }

                return nret;
            }
            catch (Exception ex)
            {
                strFanHuiZhi = ex.Message;
                return 1000;
            }
        }

        /// <summary>
        /// 获取新的密码盐值
        /// </summary>
        /// <returns></returns>
        public string GetPasswordSalt()
        {
            var salt = new byte[128 / 8];
            using (var saltnum = RandomNumberGenerator.Create())
            {
                saltnum.GetBytes(salt);
            }
            return Convert.ToBase64String(salt);
        }

        /// <summary>
        /// 获取根据盐码加密的密码
        /// </summary>
        /// <param name="password">原密码</param>
        /// <param name="salt">盐码</param>
        /// <returns></returns>
        public string GenEncodingPassword(string password
            , string salt)
        {
            MD5 md5 = MD5.Create();
            byte[] bs = Encoding.UTF8.GetBytes(password + salt);
            byte[] hs = md5.ComputeHash(bs);
            StringBuilder strb = new StringBuilder();
            foreach (byte item in hs)
            {
                strb.Append(item.ToString("x2"));
            }
            return strb.ToString();
        }



        /// <summary>
        /// 校验网络文件是否存在
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public bool JudgeFileExist(string url)
        {
            try
            {
                //创建根据网络地址的请求对象
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
                httpWebRequest.Method = "HEAD";
                httpWebRequest.Timeout = 1000;
                //返回响应状态是否是成功比较的布尔值
                return ((HttpWebResponse)httpWebRequest.GetResponse()).StatusCode == HttpStatusCode.OK;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="pToEncrypt"></param>
        /// <returns></returns>
        public string MD5Encrypt(string pToEncrypt)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
            des.Key = ASCIIEncoding.ASCII.GetBytes(strMD5Key);
            des.IV = ASCIIEncoding.ASCII.GetBytes(strMD5Key);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }

        /// <summary>
        /// MD5解密
        /// </summary>
        /// <param name="objFanHuiZhi"></param>
        /// <param name="pToDecrypt"></param>
        /// <returns></returns>
        public int MD5Decrypt(out string objFanHuiZhi, string pToDecrypt)
        {
            objFanHuiZhi = ""; int nret = 0;
            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
                for (int x = 0; x < pToDecrypt.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }

                des.Key = ASCIIEncoding.ASCII.GetBytes(strMD5Key);
                des.IV = ASCIIEncoding.ASCII.GetBytes(strMD5Key);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();

                StringBuilder ret = new StringBuilder();

                objFanHuiZhi = System.Text.Encoding.UTF8.GetString(ms.ToArray());


                return nret;
            }
            catch (Exception ex)
            {

                objFanHuiZhi = "";
                return -1;
            }

        }


        /// <summary>
        /// 身份证号隐藏打*
        /// </summary>
        /// <param name="strFanHuiZhi"></param>
        /// <param name="Value"></param>
        /// <returns></returns>
        public string ShenFenZhengHaoYinCang(string Value)
        {
            try
            {
                string encryptedIdCard = Regex.Replace(Value, @"(?<=\d{4})\d(?=\d{4})", "*");
                return encryptedIdCard;
            }
            catch (Exception ex)
            {
                return "";
            }
        }


        /// <summary>
        /// 手机号隐藏打*
        /// </summary>
        /// <param name="strFanHuiZhi"></param>
        /// <param name="Value"></param>
        /// <returns></returns>
        public string ShouJiHaoYinCang(string Value)
        {
            try
            {
                string encryptedPhone = Regex.Replace(Value, @"(?<=\d{3})\d(?=\d{4})", "*");
                return encryptedPhone;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// 获得拼音码（首拼）
        /// </summary>
        /// <param name="msg">字符串</param>
        /// <param name="islower">是否小写</param>
        /// <returns></returns>
        public string ToFirstPinyin(string msg, bool islower = true)
        {
            string result = string.Empty;
            msg = Regex.Replace(msg, @"[^\u4e00-\u9fa5]", string.Empty).Trim();
            foreach (var item in msg)
            {
                var tt = new ChineseChar(item);
                if (tt.Pinyins.Count > 0 && tt.Pinyins[0].Length > 0)
                {
                    string temp = tt.Pinyins[0].ToString();
                    if (islower)
                    {
                        temp = temp.ToLower();
                    }
                    result += temp.Substring(0, 1);
                }
            }
            return result;
        }
    }
}
